package com.tools.common.object.string;

import com.tools.common.container.OwnPairs;
import com.tools.common.container.OwnRows;
import com.tools.common.container.r.OnlyReadHashSet;
import com.tools.common.io.FileKit;
import com.tools.common.io.IOKit;
import com.tools.common.object.BasicEnum;
import com.tools.common.object.Force;
import com.tools.common.object.Note;

import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 对字符串的一些常规操作的工具类
 * 对于 StrKit 工具类的一个
 * 代码解耦。不对外开放，使用请用 StrKit 工具类调用
 * */
@Note("对字符串的一些常规操作的工具类对于 StrKit 工具类的一个代码解耦。" +
        "不对外开放，使用请用 StrKit 工具类调用")
class StringKit {

    StringKit() {}

    @Note("做正则表达式特殊字符的哈希表集合，该集合为只读集合")
    private static OnlyReadHashSet<Character> REGEXP_CHAR_SET;

    @Note("中文汉字的数组")
    private static char[] CN_WORDS;


    @Note("懒加载获取特殊字符的哈希表集合")
    public static OnlyReadHashSet<Character> getRegexCharSet() {
        if(REGEXP_CHAR_SET != null) return REGEXP_CHAR_SET;
        synchronized(StringKit.class) {
            if(REGEXP_CHAR_SET != null) return REGEXP_CHAR_SET;
            REGEXP_CHAR_SET = new OnlyReadHashSet<>(
                    '.', '$', '|', '(', ')', '[', '{', '^',
                    '?', '*', '+', '\\', '\"', '`', '\'');
            return REGEXP_CHAR_SET;
        }
    }


    @Note("取消工具类本身对 “中文汉字数组” 的强引用")
    public static void cancelChineseCharArrayQuote() {
        if(CN_WORDS == null) return;
        synchronized (StringKit.class) {
            if(CN_WORDS == null) return;
            CN_WORDS = null;
        }
    }

    @Note("取消工具类本身对 “特殊字符的哈希表集合” 的强引用")
    public static void cancelRegexCharSetQuote() {
        if(REGEXP_CHAR_SET == null) return;
        synchronized (StringKit.class) {
            if(REGEXP_CHAR_SET == null) return;
            REGEXP_CHAR_SET = null;
        }
    }


    /* ************************************************************************************************************
     *
     *          格式化操作
     *
     * ************************************************************************************************************
     * */


    @Note("调用目标对象的 toString 方法，若对象是数组则自定义输出逻辑")
    public static String toString(Object obj) {
        if(obj == null) return "null";
        if(obj.getClass().isArray()) return private_arrayToString(obj);
        return obj.toString();
    }


    @Note("遍历可迭代容器，调用每个元素的 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static String toString(String separator, Iterable<?> iterable) {
        return toString(separator, null, iterable);
    }


    @Note("遍历可迭代容器，对每个元素做自定义增强操作后调用其 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static String toString(String separator, Force forceHandle, Iterable<?> iterable) {
        if(iterable == null) return "";
        if(separator == null) separator = "";
        StringBuilder builder = new StringBuilder();
        if(forceHandle == null) {
            for (Object o : iterable) {
                builder.append(toString(o)).append(separator);
            }
        }
        else {
            for (Object o : iterable) {
                builder.append(toString(forceHandle.force(o))).append(separator);
            }
        }
        return private_stringBuilderHandle(builder, separator);
    }

    @SafeVarargs
    @Note("遍历数组，调用每个元素的 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static <T>String toString(String separator, T... array) {
        return toString(separator, null, array);
    }

    @Note("遍历数组，调用每个元素的 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static String arrayToString(String separator, Object array) {
        return arrayToString(separator, array, null);
    }

    @Note("遍历数组，对每个元素做自定义增强操作后调用其 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static String arrayToString(String separator, Object array, Force forceHandle) {
        if(array == null || !array.getClass().isArray()) return "";
        if(separator == null) separator = "";
        int length = Array.getLength(array);
        StringBuilder builder = new StringBuilder();
        if(forceHandle == null) {
            for (int i = 0; i < length; i++) {
                Object value = Array.get(array, i);
                builder.append(toString(value)).append(separator);
            }
            return private_stringBuilderHandle(builder, separator);
        }
        for (int i = 0; i < length; i++) {
            Object value = Array.get(array, i);
            Object forceNewValue = forceHandle.force(value);
            builder.append(toString(forceNewValue)).append(separator);
        }
        return private_stringBuilderHandle(builder, separator);
    }

    @SafeVarargs
    @Note("遍历数组，对每个元素做自定义增强操作后调用其 toString 方法拼接起来，其中每个元素直接用 separator 分隔")
    public static <T>String toString(String separator, Force forceHandle, T... array) {
        if(array == null || array.length == 0) return "";
        if(separator == null) separator = "";
        StringBuilder builder = new StringBuilder();
        if(forceHandle == null) {
            for (Object o : array) {
                builder.append(toString(o)).append(separator);
            }
            return private_stringBuilderHandle(builder, separator);
        }
        for (Object o : array) {
            builder.append(toString(forceHandle.force(o))).append(separator);
        }
        return private_stringBuilderHandle(builder, separator);
    }

    public static String toString(String separator, int... ints) {
        return private_basicTypeArrayToString(separator, ints, BasicEnum.INT, (ints == null) ? 0 : ints.length, null);
    }

    public static String toString(String separator, long... longs) {
        return private_basicTypeArrayToString(separator, longs, BasicEnum.LONG, (longs == null) ? 0 : longs.length, null);
    }

    public static String toString(String separator, double... doubles) {
        return private_basicTypeArrayToString(separator, doubles, BasicEnum.DOUBLE, (doubles == null) ? 0 : doubles.length, null);
    }

    public static String toString(String separator, float... floats) {
        return private_basicTypeArrayToString(separator, floats, BasicEnum.FLOAT, (floats == null) ? 0 : floats.length, null);
    }

    public static String toString(String separator, char... chars) {
        return private_basicTypeArrayToString(separator, chars, BasicEnum.CHAR, (chars == null) ? 0 : chars.length, null);
    }

    public static String toString(String separator, byte... bytes) {
        return private_basicTypeArrayToString(separator, bytes, BasicEnum.BYTE, (bytes == null) ? 0 : bytes.length, null);
    }

    public static String toString(String separator, short... shorts) {
        return private_basicTypeArrayToString(separator, shorts, BasicEnum.SHORT, (shorts == null) ? 0 : shorts.length, null);
    }

    public static String toString(String separator, boolean... booleans) {
        return private_basicTypeArrayToString(separator, booleans, BasicEnum.BOOLEAN, (booleans == null) ? 0 : booleans.length, null);
    }


    public static String toString(String separator, Force<Integer> forceHandle, int... ints) {
        return private_basicTypeArrayToString(separator, ints, BasicEnum.INT, (ints == null) ? 0 : ints.length, forceHandle);
    }

    public static String toString(String separator, Force<Long> forceHandle, long... longs) {
        return private_basicTypeArrayToString(separator, longs, BasicEnum.LONG, (longs == null) ? 0 : longs.length, forceHandle);
    }

    public static String toString(String separator, Force<Double> forceHandle, double... doubles) {
        return private_basicTypeArrayToString(separator, doubles, BasicEnum.DOUBLE, (doubles == null) ? 0 : doubles.length, forceHandle);
    }

    public static String toString(String separator, Force<Float> forceHandle, float... floats) {
        return private_basicTypeArrayToString(separator, floats, BasicEnum.FLOAT, (floats == null) ? 0 : floats.length, forceHandle);
    }

    public static String toString(String separator, Force<Character> forceHandle, char... chars) {
        return private_basicTypeArrayToString(separator, chars, BasicEnum.CHAR, (chars == null) ? 0 : chars.length, forceHandle);
    }

    public static String toString(String separator, Force<Byte> forceHandle, byte... bytes) {
        return private_basicTypeArrayToString(separator, bytes, BasicEnum.BYTE, (bytes == null) ? 0 : bytes.length, forceHandle);
    }

    public static String toString(String separator, Force<Short> forceHandle, short... shorts) {
        return private_basicTypeArrayToString(separator, shorts, BasicEnum.SHORT, (shorts == null) ? 0 : shorts.length, forceHandle);
    }

    public static String toString(String separator, Force<Boolean> forceHandle, boolean... booleans) {
        return private_basicTypeArrayToString(separator, booleans, BasicEnum.BOOLEAN, (booleans == null) ? 0 : booleans.length, forceHandle);
    }

    /* ************************************************************************************************************
     *
     *          格式化输出容器
     *
     * ************************************************************************************************************
     * */


    @Note("将键值对容器或数组容器格式化输出为类似 JSON 格式化的那种字符串")
    public static String toFormatString(Object container, String parentString) {
        if(container == null) return "null";
        if(container instanceof Map) {
            return private_kvFormatPrint(parentString, ((Map) container).entrySet());
        }
        if(container instanceof OwnPairs) {
            return private_kvFormatPrint(parentString, ((OwnPairs) container).entrySet());
        }
        if(container.getClass().isArray()) {
            return private_rowFormatPrint(parentString, container);
        }
        if(container instanceof Collection) {
            return private_rowFormatPrint(parentString, container);
        }
        if(container instanceof OwnRows) {
            return private_rowFormatPrint(parentString, container);
        }
        return container.toString();
    }


    /* ************************************************************************************************************
     *
     *          私有逻辑
     *
     * ************************************************************************************************************
     * */

    @Note("获取内置的中文汉字数组")
    static char[] default_getChineseCharArray() {
        if(CN_WORDS != null) return CN_WORDS;
        synchronized(StringKit.class) {
            if(CN_WORDS != null) return CN_WORDS;
            InputStream input = FileKit.getResourceInputStream("custom/ChineseWord.txt");
            String cnWordString = IOKit.readToString(input);
            CN_WORDS = cnWordString.toCharArray();
            return CN_WORDS;
        }
    }

    @Note("数组的输出逻辑，若是多维数组，则采用递归调用")
    private static String private_arrayToString(Object array) {
        StringBuilder builder = new StringBuilder("[");
        int length = Array.getLength(array);
        for (int i = 0; i < length; i++) {
            Object value = Array.get(array, i);
            String s = toString(value);
            if(i == length - 1) {
                builder.append(s);
                break;
            }
            builder.append(s).append(", ");
        }
        return builder.append("]").toString();
    }


    @Note("对于有分隔符的拼接输出，要裁掉最后一个分隔符才是完整的标准输出格式")
    private static String private_stringBuilderHandle(StringBuilder builder, String separator) {
        if(builder.length() != 0) {
            return builder.substring(0, builder.length() - separator.length());
        }
        return builder.toString();
    }


    @Note("将基本类型数组的元素按指定分隔符拼接成固定格式的字符串输出")
    private static String private_basicTypeArrayToString(String separator, Object array, BasicEnum basic, int length, Force forceHandle) {
        if(length == 0) return "";
        if(separator == null) separator = "";
        StringBuilder builder = new StringBuilder();
        if(forceHandle == null) {
            switch (basic) {
                case INT: {int[] is = (int[]) array;for(int i : is) builder.append(i).append(separator);} break;
                case LONG: {long[] ls = (long[]) array; for(long l : ls) builder.append(l).append(separator);} break;
                case DOUBLE: {double[] ds = (double[]) array; for(double d : ds) builder.append(d).append(separator);} break;
                case FLOAT: {float[] fs = (float[]) array; for(float f : fs) builder.append(f).append(separator);} break;
                case CHAR: {char[] cs = (char[]) array; for(char c : cs) builder.append(c).append(separator);} break;
                case BYTE: {byte[] bs = (byte[]) array; for(byte b : bs) builder.append(b).append(separator);} break;
                case SHORT: {short[] ss = (short[]) array; for(short s : ss) builder.append(s).append(separator);} break;
                case BOOLEAN: {boolean[] bs = (boolean[]) array; for(boolean b : bs) builder.append(b).append(separator);} break;
            }
        }
        else {
            switch (basic) {
                case INT: {
                    int[] is = (int[]) array;
                    for(int i : is) {
                        Object v = forceHandle.force(i);
                        builder.append(v == null ? 0 : v).append(separator);
                    }
                } break;
                case LONG: {
                    long[] ls = (long[]) array;
                    for(long l : ls) {
                        Object v = forceHandle.force(l);
                        builder.append(v == null ? 0 : v).append(separator);
                    }
                } break;
                case DOUBLE: {
                    double[] ds = (double[]) array;
                    for(double d : ds) {
                        Object v = forceHandle.force(d);
                        builder.append(v == null ? 0.0 : v).append(separator);
                    }
                } break;
                case FLOAT: {
                    float[] fs = (float[]) array;
                    for(float f : fs) {
                        Object v = forceHandle.force(f);
                        builder.append(v == null ? 0.0 : v).append(separator);
                    }
                } break;
                case CHAR: {
                    char[] cs = (char[]) array;
                    for(char c : cs) {
                        Object v = forceHandle.force(c);
                        builder.append(v == null ? BasicEnum.CHAR.getDefaultValue() : v).append(separator);
                    }
                } break;
                case BYTE: {
                    byte[] bs = (byte[]) array;
                    for(byte b : bs) {
                        Object v = forceHandle.force(b);
                        builder.append(v == null ? 0 : v).append(separator);
                    }
                } break;
                case SHORT: {
                    short[] ss = (short[]) array;
                    for(short s : ss) {
                        Object v = forceHandle.force(s);
                        builder.append(v == null ? 0 : v).append(separator);
                    }
                } break;
                case BOOLEAN: {
                    boolean[] bs = (boolean[]) array;
                    for(boolean b : bs) {
                        Object v = forceHandle.force(b);
                        builder.append(v == null ? false : v).append(separator);
                    }
                }
            }
        }
        return private_stringBuilderHandle(builder, separator);
    }


    @Note("键值对容器的格式化输出，类似于 JSON 对象字符串的那种")
    private static String private_kvFormatPrint(String parent, Set entrySet) {
        StringBuilder builder = new StringBuilder(parent).append('{');
        for (Object o : entrySet) {
            Map.Entry e = (Map.Entry) o;
            builder.append("\n\t").append(parent)
                    .append(StrKit.toString(e.getKey()))
                    .append("=");
            Object value = e.getValue();
            if(value == null) {
                builder.append("null");
                continue;
            }
            if(value instanceof Map) {
                String s = private_kvFormatPrint(parent + "\t", ((Map) value).entrySet());
                builder.append(StrKit.trimLeft(s));
                continue;
            }
            if(value instanceof OwnPairs) {
                String s = private_kvFormatPrint(parent + "\t", ((OwnPairs) value).entrySet());
                builder.append(StrKit.trimLeft(s));
                continue;
            }
            if(value.getClass().isArray()) {
                String s = private_rowFormatPrint(parent + "\t", value);
                builder.append(StrKit.trimLeft(s));
                continue;
            }
            if(value instanceof Collection) {
                String s = private_rowFormatPrint(parent + "\t", value);
                builder.append(StrKit.trimLeft(s));
                continue;
            }
            if(value instanceof OwnRows) {
                String s = private_rowFormatPrint(parent + "\t", value);
                builder.append(StrKit.trimLeft(s));
                continue;
            }
            builder.append(StrKit.toString(value));
        }
        builder.append("\n").append(parent).append('}');
        return builder.toString();
    }

    @Note("数组容器的格式化输出，类似于 JSON 数组字符串的那种")
    private static String private_rowFormatPrint(String parent, Object row) {
        StringBuilder builder = new StringBuilder(parent)
                .append('[');
        //数组
        if(row.getClass().isArray()) {
            int length = Array.getLength(row);
            for (int i = 0; i < length; i++) {
                private_rowFormatToStringOperation(builder, parent, Array.get(row, i));
            }
        }
        else if(row instanceof Collection) {
            for (Object o : (Collection) row) {
                private_rowFormatToStringOperation(builder, parent, o);
            }
        }
        else {
            for (Object o : (OwnRows) row) {
                private_rowFormatToStringOperation(builder, parent, o);
            }
        }
        return builder.substring(0, builder.length() - 1) + '\n' + parent + ']';
    }

    @Note("数组容器的格式化输出的内部逻辑")
    private static void private_rowFormatToStringOperation(StringBuilder builder, String parent, Object o) {
        builder.append("\n\t")
                .append(parent);
        if(o == null) {
            builder.append("null,");
            return;
        }
        if(o.getClass().isArray()) {
            String s = private_rowFormatPrint(parent + "\t", o);
            builder.append(StrKit.trimLeft(s));
            return;
        }
        if(o instanceof Map) {
            String s = private_kvFormatPrint(parent + "\t", ((Map) o).entrySet());
            builder.append(StrKit.trimLeft(s));
            return;
        }
        if(o instanceof OwnPairs) {
            String s = private_kvFormatPrint(parent + "\t", ((OwnPairs) o).entrySet());
            builder.append(StrKit.trimLeft(s));
            return;
        }
        builder.append(StrKit.toString(o)).append(",");
    }

    /* ************************************************************************************************************
     *
     *
     *          判空操作
     *
     * ************************************************************************************************************
     * */

    public static boolean isNull(String str) {
        return str == null;
    }

    public static boolean isAllNull(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(str != null) return false;
        return true;
    }

    public static boolean isAllNull(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str != null) return false;
        return true;
    }

    public static boolean isAllNull(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str != null) return false;
        return true;
    }

    public static boolean isAllNull(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() != null) return false;
        return true;
    }

    public static boolean isAnyNull(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(str == null) return true;
        return false;
    }

    public static boolean isAnyNull(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str == null) return true;
        return false;
    }

    public static boolean isAnyNull(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str == null) return true;
        return false;
    }

    public static boolean isAnyNull(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next() == null) return true;
        return false;
    }

    public static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }

    public static boolean isAllEmpty(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(notEmpty(str)) return false;
        return true;
    }

    public static boolean isAllEmpty(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notEmpty(str)) return false;
        return true;
    }

    public static boolean isAllEmpty(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notEmpty(str)) return false;
        return true;
    }

    public static boolean isAllEmpty(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notEmpty(iterator.next())) return false;
        return true;
    }

    public static boolean isAnyEmpty(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(isEmpty(str)) return true;
        return false;
    }

    public static boolean isAnyEmpty(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isEmpty(str)) return true;
        return false;
    }

    public static boolean isAnyEmpty(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isEmpty(str)) return true;
        return false;
    }

    public static boolean isAnyEmpty(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isEmpty(iterator.next())) return true;
        return false;
    }

    public static boolean isBlank(String str) {
        if(str == null || str.isEmpty()) return true;
        for (int i = 0; i < str.length(); i++) {
            if(!Character.isWhitespace(str.charAt(i))) return false;
        }
        return true;
    }

    public static boolean isAllBlank(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(notBlank(str)) return false;
        return true;
    }

    public static boolean isAllBlank(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notBlank(str)) return false;
        return true;
    }

    public static boolean isAllBlank(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notBlank(str)) return false;
        return true;
    }

    public static boolean isAllBlank(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notBlank(iterator.next())) return false;
        return true;
    }

    public static boolean isAnyBlank(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(isBlank(str)) return true;
        return false;
    }

    public static boolean isAnyBlank(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isBlank(str)) return true;
        return false;
    }

    public static boolean isAnyBlank(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isBlank(str)) return true;
        return false;
    }

    public static boolean isAnyBlank(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isBlank(iterator.next())) return true;
        return false;
    }

    public static boolean notNull(String str) {
        return str != null;
    }

    public static boolean notAllNull(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(str == null) return false;
        return true;
    }

    public static boolean notAllNull(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str == null) return false;
        return true;
    }

    public static boolean notAllNull(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str == null) return false;
        return true;
    }

    public static boolean notAllNull(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next()  == null) return false;
        return true;
    }

    public static boolean notAnyNull(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(str != null) return true;
        return false;
    }

    public static boolean notAnyNull(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str != null) return true;
        return false;
    }

    public static boolean notAnyNull(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(str != null) return true;
        return false;
    }

    public static boolean notAnyNull(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(iterator.next()  != null) return true;
        return false;
    }

    public static boolean notEmpty(String str) {
        return str != null && !str.isEmpty();
    }

    public static boolean notAllEmpty(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(isEmpty(str)) return false;
        return true;
    }

    public static boolean notAllEmpty(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isEmpty(str)) return false;
        return true;
    }

    public static boolean notAllEmpty(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isEmpty(str)) return false;
        return true;
    }

    public static boolean notAllEmpty(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isEmpty(iterator.next())) return false;
        return true;
    }

    public static boolean notAnyEmpty(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(notEmpty(str)) return true;
        return false;
    }

    public static boolean notAnyEmpty(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notEmpty(str)) return true;
        return false;
    }

    public static boolean notAnyEmpty(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notEmpty(str)) return true;
        return false;
    }

    public static boolean notAnyEmpty(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notEmpty(iterator.next())) return true;
        return false;
    }

    public static boolean notBlank(String str) {
        return !isBlank(str);
    }

    public static boolean notAllBlank(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(isBlank(str)) return false;
        return true;
    }

    public static boolean notAllBlank(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isBlank(str)) return false;
        return true;
    }

    public static boolean notAllBlank(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(isBlank(str)) return false;
        return true;
    }

    public static boolean notAllBlank(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(isBlank(iterator.next())) return false;
        return true;
    }

    public static boolean notAnyBlank(String... s) {
        if(s == null || s.length == 0) return false;
        for (String str : s) if(notBlank(str)) return true;
        return false;
    }

    public static boolean notAnyBlank(Collection<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notBlank(str)) return true;
        return false;
    }

    public static boolean notAnyBlank(OwnRows<String> s) {
        if(s == null || s.isEmpty()) return false;
        for (String str : s) if(notBlank(str)) return true;
        return false;
    }

    public static boolean notAnyBlank(Iterable<String> s) {
        if(s == null) return false;
        Iterator<String> iterator = s.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext()) if(notBlank(iterator.next())) return true;
        return false;
    }

    /* ************************************************************************************************************
     *
     *
     *          比较操作
     *
     * ************************************************************************************************************
     * */

    public static boolean equals(String source, String target) {
        return Objects.equals(source, target);
    }

    public static boolean equalsAll(String source, String... targets) {
        if(targets == null || targets.length == 0) return false;
        for (String s : targets) if(!Objects.equals(source, s)) return false;
        return true;
    }

    public static boolean equalsAll(String source, Collection<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(!Objects.equals(source, s)) return false;
        return true;
    }

    public static boolean equalsAll(String source, OwnRows<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(!Objects.equals(source, s)) return false;
        return true;
    }

    public static boolean equalsAll(String source, Iterable<String> targets) {
        if(targets == null) return false;
        Iterator<String> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(!Objects.equals(source, iterator.next())) return false;
        return true;
    }

    public static boolean equalsAny(String source, String... targets) {
        if(targets == null || targets.length == 0) return false;
        for (String s : targets) if(Objects.equals(source, s)) return true;
        return false;
    }

    public static boolean equalsAny(String source, Collection<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(Objects.equals(source, s)) return true;
        return false;
    }

    public static boolean equalsAny(String source, OwnRows<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(Objects.equals(source, s)) return true;
        return false;
    }

    public static boolean equalsAny(String source, Iterable<String> targets) {
        if(targets == null) return false;
        Iterator<String> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(Objects.equals(source, iterator.next())) return true;
        return false;
    }

    public static boolean equalsIgnoreCase(String source, String target) {
        return (source == null) ? target == null : source.equalsIgnoreCase(target);
    }

    public static boolean equalsIgnoreCaseAll(String source, String... targets) {
        if(targets == null || targets.length == 0) return false;
        for (String s : targets) if(!equalsIgnoreCase(source, s)) return false;
        return true;
    }

    public static boolean equalsIgnoreCaseAll(String source, Collection<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(!equalsIgnoreCase(source, s)) return false;
        return true;
    }

    public static boolean equalsIgnoreCaseAll(String source, OwnRows<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(!equalsIgnoreCase(source, s)) return false;
        return true;
    }

    public static boolean equalsIgnoreCaseAll(String source, Iterable<String> targets) {
        if(targets == null) return false;
        Iterator<String> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(!equalsIgnoreCase(source, iterator.next())) return false;
        return true;
    }

    public static boolean equalsIgnoreCaseAny(String source, String... targets) {
        if(targets == null || targets.length == 0) return false;
        for (String s : targets) if(equalsIgnoreCase(source, s)) return true;
        return false;
    }

    public static boolean equalsIgnoreCaseAny(String source, Collection<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(equalsIgnoreCase(source, s)) return true;
        return false;
    }

    public static boolean equalsIgnoreCaseAny(String source, OwnRows<String> targets) {
        if(targets == null || targets.isEmpty()) return false;
        for (String s : targets) if(equalsIgnoreCase(source, s)) return true;
        return false;
    }

    public static boolean equalsIgnoreCaseAny(String source, Iterable<String> targets) {
        if(targets == null) return false;
        Iterator<String> iterator = targets.iterator();
        if(!iterator.hasNext()) return false;
        while (iterator.hasNext())  if(equalsIgnoreCase(source, iterator.next())) return true;
        return false;
    }


}
